import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Observable;
import java.util.Observer;
import java.util.StringTokenizer;

import org.apache.commons.net.telnet.TelnetClient;
import org.apache.commons.net.telnet.TelnetNotificationHandler;
import org.apache.commons.net.telnet.SimpleOptionHandler;
import org.apache.commons.net.telnet.EchoOptionHandler;
import org.apache.commons.net.telnet.TerminalTypeOptionHandler;
import org.apache.commons.net.telnet.SuppressGAOptionHandler;
import org.apache.commons.net.telnet.InvalidTelnetOptionException;

public class Telnet implements Observer{
	private static TelnetClient tc = null;
	private static Telnet tr = null;
	private static TelnetRead telr = null;
	private static TelnetWrite telw = null;

	public boolean timerExecute = false;
	public long responseTime = 0;
	
	public enum Direction{
		RIGHT(3),LEFT(1),UP(5),DOWN(2),RLEFT(4),RRIGHT(6),FLOAT(7);
		public int direction;
		private Direction(int direction){
			this.direction = direction;
		}
	}
	
	private Telnet() throws Exception{
		tc = new TelnetClient();
		telr = new TelnetRead(tc,this);
		telr.connect("192.168.1.6", 2000);
		telw = new TelnetWrite(tc);
		pingThread();		
	}
	
	private void pingThread(){
		Thread pThread = new Thread(new Runnable(){
			public void run(){
				try {
					while(tc.sendAYT(5000)){
						timerExecute = true;
						responseTime = 0;
						telw.sendPing();
						while(timerExecute){
							responseTime++;
							Thread.sleep(1);
							if(responseTime>750)
								timerExecute = false;
						}
						if(responseTime<750)
							Thread.sleep(750-responseTime);
					}
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		});
		pThread.start();
	}
	
	public static Telnet getTelnet() throws Exception{
		if(tr == null)	tr = new Telnet();
		return tr;
	}
	
	public TelnetClient getClient(){
		return tc;
	}
	
	public TelnetWrite getWrite(){
		return telw;
	}
	
	public void ping(){
		String ip = "192.168.1.6";
        String pingResult = "";
        String subResult = "";
        String pingCmd = "ping " + ip + " -n 1";
        try {
            Runtime r = Runtime.getRuntime();
            Process p = r.exec(pingCmd);

            BufferedReader in = new BufferedReader(new
            InputStreamReader(p.getInputStream()));
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                //System.out.println(inputLine);
                pingResult += inputLine;
            }
            System.out.println(pingResult.substring(52, 92));
            in.close();

        } catch (IOException e) {
            System.out.println(e);
        }
	}
	
	private void handleInput(char stream){
		switch(stream){
		case '0':
			CopterInfo.getCI().setState("IDLE");
			break;
		case '1':
			CopterInfo.getCI().setState("LEFT");
			break;
		case '2':
			CopterInfo.getCI().setState("DOWN");
			break;
		case '3':
			CopterInfo.getCI().setState("RIGHT");
			break;
		case '4':
			CopterInfo.getCI().setState("RLEFT");
			break;
		case '5':
			CopterInfo.getCI().setState("UP");
			break;
		case '6':
			CopterInfo.getCI().setState("RRIGHT");
			break;
		case '7':
			CopterInfo.getCI().setState("FLOAT");
			break;
		case 'T':
			//System.out.println("Received Timerupdate");
			break;
		case 'P':
			System.out.print("P");
			timerExecute = false;
			CopterInfo.getCI().setResponseTime(responseTime);
			break;
		default:
			break;
		}
	}

	public void update(Observable arg0, Object arg1) {
		//System.out.println("update(" + arg0 + "," + arg1 + ");");
		handleInput((Character) arg1);
	}
	
}
